/**
 * Copyright (c) 2004-2015 All Rights Reserved.
 */
package com.zbest.zpay.gw.service.impl;

import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.zbest.common.lang.enums.BizCode;
import com.zbest.common.lang.exception.ZpayException;
import com.zbest.zpay.gw.assemble.MessageAssembleManager;
import com.zbest.zpay.gw.model.GwBizCode;
import com.zbest.zpay.gw.model.MessageContext;
import com.zbest.zpay.gw.model.MessageDirection;
import com.zbest.zpay.gw.processor.MessageProcessorManager;
import com.zbest.zpay.service.gw.MessageSenderService;
import com.zbest.zpay.service.gw.model.GwKeyEnum;
import com.zbest.zpay.service.gw.model.GwResult;

/**
 * 
 *
 * @author czhou3306@gmail.com
 * @version $Id: WeixinServiceImpl.java, v0.1 2015年11月17日 下午5:52:19
 *          czhou3306@gmail.com Exp $
 */
@Service("messageSenderService")
public class MessageSenderServiceImpl implements MessageSenderService {

    private static final Logger     logger = LoggerFactory
                                               .getLogger(MessageSenderServiceImpl.class);

    @Resource
    private MessageAssembleManager  messageAssembleManager;

    @Resource
    private MessageProcessorManager messageProcessorManager;

    /**
     * @see com.zbest.zpay.service.gw.MessageSenderService#syncSend(java.lang.String,
     *      java.lang.String, java.util.Map)
     */
    @Override
    public GwResult syncSend(String channelId, Map<String, Object> data) {

        return process(channelId, MessageDirection.SEND, data);
    }

    private GwResult process(String channelId, MessageDirection direction, Map<String, Object> data) {
        GwResult result = new GwResult();
        try {
            MessageContext context = messageProcessorManager.process(channelId, direction, data);
            result.setCode(GwBizCode.SUCCESS);
            result.getResultData().putAll(context.getResponseData());
        } catch (ZpayException e) {
            logger.error("同步处理异常channelId=" + channelId + ",data=" + data, e);
            result.setCode(e.getCode());
        } catch (Exception e) {
            logger.error("同步处理系统异常channelId=" + channelId + ",data=" + data, e);
            result.setCode(BizCode.SYSTEM_EXCEPTION);
        }
        return result;
    }

    /**
     * @see com.zbest.zpay.service.gw.MessageSenderService#assemble(java.lang.String,
     *      java.lang.String, java.util.Map)
     */
    @Override
    public GwResult assemble(String channelId, Map<String, Object> data) {

        logger.info("组装报文请求channelId=" + channelId + ",data=" + data);
        GwResult result = new GwResult();
        try {

            MessageContext context = new MessageContext();
            context.setChannelId(channelId);
            context.setRequestData(data);
            messageAssembleManager.assemble(context);
            result.setCode(GwBizCode.SUCCESS);
            result.getResultData().putAll(context.getResponseData());
            result.getResultData().put(GwKeyEnum.MESSAGE_CONTENT.getCode(),
                context.getSendMessage());
        } catch (ZpayException e) {
            logger.error("报文组装发生异常channelId=" + channelId + ",data=" + data, e);
            result.setCode(e.getCode());
        } catch (Exception e) {
            logger.error("报文组装发生系统异常channelId=" + channelId + ",data=" + data, e);
            result.setCode(BizCode.SYSTEM_EXCEPTION);
        }
        return result;
    }

    /**
     * @see com.zbest.zpay.service.gw.MessageSenderService#syncReceive(java.lang.String,
     *      java.util.Map)
     */
    @Override
    public GwResult syncReceive(String channelId, Map<String, Object> data) {

        return process(channelId, MessageDirection.RECEIVE, data);
    }

}
